package cn.iotab.iotkit.transport.api.access.device;

import cn.iotab.iotkit.transport.api.access.handler.DeviceSessionHandler;
import cn.iotab.iotkit.transport.api.access.handler.ToServerRpcHandler;
import cn.iotab.iotkit.transport.api.access.handler.impl.DefaultProductMessageHandler;
import lombok.Getter;

import java.util.Collections;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class HandlerManager {

    /**
     * 设备消息处理器
     * productKey to handlerGroup
     */
    private final Map<String/*productKey*/, DefaultProductMessageHandler> handlerGroupMap = new ConcurrentHashMap<>();

    /**
     * 处理transport RPC消息
     */
    @Getter
    private final ToServerRpcHandler toServerRpcHandler;

    /**
     * 用户自定义SessionHandler
     */
    @Getter
    private final DeviceSessionHandler deviceSessionHandler;


    public HandlerManager(ToServerRpcHandler toServerRpcHandler, DeviceSessionHandler deviceSessionHandler) {
        this.toServerRpcHandler = toServerRpcHandler;
        this.deviceSessionHandler = deviceSessionHandler;
    }

    /**
     * add handler group for a productKey
     * @param productKey
     * @param productProcessor
     * @return
     */
    public final HandlerManager addProduct(String productKey, DefaultProductMessageHandler productProcessor){
        DefaultProductMessageHandler exist = handlerGroupMap.putIfAbsent(productKey, productProcessor);
        if (exist != null){
            throw new IllegalStateException("handlerGroup for product " + productKey + " already exist");
        }
        return this;
    }

    public final HandlerManager addDefaultProductProcessor(DefaultProductMessageHandler productProcessor){
        DefaultProductMessageHandler exist = handlerGroupMap.putIfAbsent("*", productProcessor);
        if (exist != null){
            throw new IllegalStateException("default handlerGroup already exist");
        }
        return this;
    }

    public final DefaultProductMessageHandler getProductHandler(String productKey){
        return handlerGroupMap.get(productKey);
    }

    public final DefaultProductMessageHandler getHandlerProductHandlerOrDefault(String productKey){
        DefaultProductMessageHandler group = getProductHandler(productKey);
        if (group != null){
            return group;
        }
        return getDefaultProductHandler();
    }

    public final DefaultProductMessageHandler getDefaultProductHandler(){
        return handlerGroupMap.get("*");
    }

    public final Map<String, DefaultProductMessageHandler> getAllProductHandler(){
        return Collections.unmodifiableMap(handlerGroupMap);
    }

    public void check() {
        checkNotNull(this.toServerRpcHandler, "toServerRpcHandler is null");
        checkNotNull(this.handlerGroupMap, "QueryProfileListener is null");
        if (this.handlerGroupMap.size() == 0){
            throw new IllegalStateException("handlerGroupMap is empty");
        }
    }

    private static void checkNotNull(Object obj, String errMsg){
        if (obj == null){
            throw new NullPointerException(errMsg);
        }
    }


}
